﻿#pragma once
#pragma warning (disable : 4819)
#include <AsDebug>
#include <AsException>
#include <AsObject>
#include <AsAlgorithmExecutor>
#define AL_NAMESPACE AL

// 类定义 
namespace AL_NAMESPACE {

	class InputImages : public AsObject {
		AS_OBJECT(InputImages);
		AS_PROPERTY(mat1);

	public:
		cv::Mat mat1;
		// ...
		
	};

	// 输入参数
	class InputParams : public AsObject {
		AS_OBJECT(InputParams);
		AS_PROPERTY(mode);

	public:
		int mode = 0;
		// ...

	};

	// 输出结果
	class OutputResult : public AsObject {
		AS_OBJECT(OutputResult);
		AS_PROPERTY(ret);

	public:
		int ret = 0;
		// ...

	};

};

// 常量定义（算法无需理解）
namespace AL_NAMESPACE {

	const std::string dllName = "algorithm_dll_name";

	// 函数选项
	enum Function {
		FunctionDefault
		// ...
	};

};

// 关键函数定义（算法无需理解）
namespace AL_NAMESPACE {
	
	inline void fromInput(AsContainer& conta, const InputImages& images, const InputParams& params) {
		if (conta.contains("InputImages")) 
			conta.setProperty("InputImages", AsContainer::None);
		if (conta.contains("InputParams"))
			conta.setProperty("InputParams", AsContainer::None);
		conta.setConst("InputImages", images);
		conta.setConst("InputParams", params);
	}
	inline void fromOutput(AsContainer& conta, const OutputResult& result) {
		if (conta.contains("OutputResult"))
			conta.setProperty("OutputResult", AsContainer::None);
		conta.setConst("OutputResult", result);
	}
	inline void toInput(const AsContainer& conta, InputImages& images, InputParams& params) {
		if (conta.contains("InputImages"))
			images.from(conta.getVariant("InputImages").toObject());
		else AsDebug() << "[AsAlgorithm] not contains \"InputImages\"";
		if (conta.contains("InputParams"))
			params.from(conta.getVariant("InputParams").toObject());
		else AsDebug() << "[AsAlgorithm] not contains \"InputParams\"";
	}
	inline void toOutput(const AsContainer& conta, OutputResult& result) {
		if (conta.contains("OutputResult"))
			result.from(conta.getVariant("OutputResult").toObject());
		else AsDebug() << "[AsAlgorithm] not contains \"OutputResult\"";
	}
	inline void showInfos(const InputImages& images, const InputParams& params, const OutputResult& result) {
		AsDebug() << "InputImages:" << images.tostr();
		AsDebug() << "InputParams:" << params.tostr();
		AsDebug() << "OutputResult:" << result.tostr();
	}
	
};

// 算法执行器
namespace AL_NAMESPACE {

	class AlgorithmExecutor : public AsAlgorithmExecutorA {
	public:
		AlgorithmExecutor() : AsAlgorithmExecutorA(dllName) {}

	private:
		InputImages		images;
		InputParams		params;
		OutputResult	result;

	public:
		void showInfos() {
			AL_NAMESPACE::showInfos(images, params, result);
		}
		void execute(Function function = FunctionDefault) {
			if (conta().contains("function"))
				conta().setProperty("function", AsContainer::None);
			conta().setConst("function", (int)function);
			AL_NAMESPACE::fromInput(conta(), images, params);
			AsAlgorithmExecutorA::execute();
			AL_NAMESPACE::toOutput(conta(), result);
		}
		void execute(const InputImages& images, const InputParams& params, Function function = FunctionDefault) {
			this->images = images;
			this->params = params;
			execute();
		}
		InputImages& getInputImages() {
			return images;
		}
		InputParams& getInputParams() {
			return params;
		}
		OutputResult& getResult() {
			return result;
		}

	};

};